package com.dagene.weixin.service;

import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import net.sf.json.JSONObject;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.dagene.weixin.entity.AccessState;
import com.dagene.weixin.entity.ChatMsg;
import com.dagene.weixin.entity.CustomerRemark;
import com.dagene.weixin.entity.CustomerService;
import com.dagene.weixin.entity.KefuNum;
import com.dagene.weixin.entity.WeixinUserInfo;
import com.dagene.weixin.repository.AccessStateDao;
import com.dagene.weixin.repository.CustomerServiceDao;
import com.dagene.weixin.util.Constants;
import com.dagene.weixin.util.MediaUtil;
import com.dagene.weixin.util.PushUtil;
import com.dagene.weixin.util.Util;

@Component
@Transactional
public class ChatUtilService {
	@Autowired
	ChatMsgService chatMsgService;
	@Autowired
	UserService userService;
	@Autowired
	CustomerServiceDao mallCustomerServiceDao;
	@Autowired
	AccessStateDao accessStateDao;

	/**
	 * 处理聊天
	 * 
	 * @param reqContent
	 * @param chatmsg
	 * @return
	 * @throws Exception
	 */
	public String processChat(String reqContent, ChatMsg chatmsg)
			throws Exception {
		String respContent = "";
		// 判断当前是否是客服
		CustomerService mcs = mallCustomerServiceDao.findOneByOpenid(chatmsg
				.getOpenid());
		// 客服接入用户
		if (mcs != null && Util.isInteger(reqContent)
				&& !reqContent.equals("401") && !reqContent.equals("402")) {
			respContent = processAccess(mcs, reqContent, chatmsg);
		}
		// 查询未接入的用户
		else if (reqContent.equals("402") && mcs != null) {
			List<AccessState> list = chatMsgService.getUnAccessUsers();
			if (list.size() == 0) {
				respContent = "暂无未接入用户！";
			} else {
				for (AccessState accessState : list) {
					respContent += accessState.getMatchnumber() + "\n";
				}
			}
		}
		// 客服给当前客户设置备注
		else if (reqContent.indexOf("set") == 0 && mcs != null) {
			int index = reqContent.indexOf("set") + 3;
			CustomerRemark cr = chatMsgService.getCustomerRemark(mcs
					.getOpenid());
			cr.setName(reqContent.substring(index));
			chatMsgService.saveCustomerRemark(cr);

			respContent = "设置备注成功！";
		}
		// 发送聊天信息
		else {
			respContent = sendText(mcs, reqContent, chatmsg);
		}
		return respContent;
	}

	/**
	 * 发送聊天信息
	 * 
	 * @param mcs
	 * @param reqContent
	 * @param chatmsg
	 * @return
	 * @throws Exception
	 */
	private String sendText(CustomerService mcs, String reqContent,
			ChatMsg chatmsg) throws Exception {
		String respContent = "";
		// 当前用户是否连接成功
		String state = checkAccessState(chatmsg.getOpenid());
		// 当前客服是否连接成功
		AccessState as400 = chatMsgService.isAccess400(chatmsg.getOpenid());

		if (state.equals("") || as400 != null) {
			// 根据当前消息发送者的openid查询连接状态的openid信息，若查得到为用户，否则为客服
			AccessState as = chatMsgService.findByOpercodeAndOpenid(
					Constants.ACCESS_SUCCESS_STATE, chatmsg.getOpenid());

			// 关闭客服聊天
			if (reqContent.equals("401")) {
				AccessState state2 = null;
				if (as == null) {
					state2 = as400;
					chatmsg.setOrigin((short) 1);
				} else {
					state2 = as;
					chatmsg.setOrigin((short) 0);
				}
				String worker = state2.getWorker();

				if (!StringUtils.isEmpty(worker)) {
					chatMsgService
							.kefuTurnOffAccess(state2.getOpenid(), worker);
					new PushUtil().sendResponse(state2.getOpenid(), "会话被关闭！");
					new PushUtil().sendResponse(state2.getWorker(), "会话被关闭！");
					chatmsg.setMessage("401");
					chatmsg.setOpenid(state2.getOpenid());
					chatmsg.setWorker(state2.getWorker());
					chatmsg.setMatchnumber(state2.getMatchnumber());
					chatMsgService.saveChatMsg(chatmsg);

					List<AccessState> list = chatMsgService.getUnAccessUsers();
					if (list.size() > 0) {
						respContent = "当前还有以下客户未接入：\n";
						for (AccessState accessState : list) {
							respContent += accessState.getMatchnumber() + "\n";
						}
						new PushUtil().sendResponse(state2.getWorker(),
								respContent);
					}
					return "success";
				} else {
					respContent = "未取到客服信息";
				}
			}
			// 用户发起消息
			else if (as != null) {
				chatmsg.setOrigin((short) 0);
				JSONObject obj = new PushUtil().sendResponse(as.getWorker(),
						reqContent);

				System.out.println("user-worker: " + as.getWorker()
						+ ";content: " + reqContent + ";result: "
						+ obj.toString());

				chatmsg.setOpenid(as.getOpenid());
				chatmsg.setWorker(as.getWorker());
				chatmsg.setMatchnumber(as.getMatchnumber());
			}
			// 客服发消息
			else {
				chatmsg.setOrigin((short) 1);
				JSONObject obj = new PushUtil().sendResponse(as400.getOpenid(),
						reqContent);

				System.out.println("worker-user: " + as400.getWorker()
						+ ";content: " + reqContent + ";result: "
						+ obj.toString());

				chatmsg.setOpenid(as400.getOpenid());
				chatmsg.setWorker(as400.getWorker());
				chatmsg.setMatchnumber(as400.getMatchnumber());
			}

			reqContent = Util.filterExpression(reqContent);
			chatmsg.setMessage(reqContent);
			chatMsgService.saveChatMsg(chatmsg);
			return "success";
		}
		return state;
	}

	/**
	 * 处理聊天接入，包括重新接入聊天
	 * 
	 * @param mcs
	 * @param reqContent
	 * @param chatmsg
	 * @return
	 * @throws Exception
	 */
	public synchronized String processAccess(CustomerService mcs,
			String reqContent, ChatMsg chatmsg) throws Exception {
		String respContent = "";
		// 查询当前客服在连接状态中是否存在
		AccessState accessState1 = chatMsgService.isAccess400(chatmsg
				.getOpenid());
		if (accessState1 != null) {
			respContent = "你还有未结束的聊天，请回复401先结束之前的聊天，再回复编号接新的聊天！";
		}
		// 客服重新接入原聊天
		else if (reqContent.substring(0, 1).equals("0")) {
			int matchnumber = Integer.parseInt(reqContent.substring(1));
			List<ChatMsg> list = chatMsgService.getChatMsg(matchnumber);
			if (list.size() > 0) {
				// 判断最新一条记录的客服与当前客服是否一致
				if (list.get(0).getWorker().equals(chatmsg.getOpenid())) {
					ChatMsg chatMsg = list.get(0);
					long dayOffset = new Date().getTime()
							- chatMsg.getTime().getTime();
					// 聊天时间间隔在48小时之内
					if (dayOffset <= Constants.ACCESS_TWO_DAY_TIME) {
						AccessState accessState = new AccessState();
						accessState.setOpenid(chatMsg.getOpenid());
						accessState.setOpercode(Constants.ACCESS_SUCCESS_STATE);
						accessState.setMatchnumber(matchnumber);
						accessState.setTime(chatmsg.getTime());
						accessState.setWorker(chatMsg.getWorker());
						chatMsgService.saveAccessState(accessState);

						chatmsg.setMessage(reqContent);
						chatmsg.setMatchnumber(accessState.getMatchnumber());
						chatmsg.setWorker(accessState.getWorker());
						chatMsgService.saveChatMsg(chatmsg);
						respContent = "重新接入成功！";
						new PushUtil().sendResponse(accessState.getOpenid(),
								"聊天重新被原客服接入！");
					} else {
						respContent = "聊天超过48小时，无法重新接入";
					}
				} else {
					respContent = "该用户已在聊天中，不能接入！";
				}
			} else {
				respContent = "没有该记录！";
			}
		}
		// 接入聊天
		else {
			// 根据聊天编号去查找是否有相对应的未接入状态
			AccessState accessState = chatMsgService
					.getUnAccessUsersByMatchnumber(Integer.parseInt(reqContent));

			if (accessState != null) {
				AccessState accessMsg = chatMsgService.accessUser(
						accessState.getOpenid(), chatmsg.getOpenid());
				if (accessMsg != null) {
					new PushUtil().sendResponse(accessState.getOpenid(),
							"您好！我是客服：" + mcs.getName() + "，有什么可以帮助您？");
					WeixinUserInfo user = chatMsgService
							.getWeixinUserInfo(accessState.getOpenid());
					respContent = "接入成功！当前用户昵称为： " + user.getNickname();
					if (user.getHeadimgurl() != null
							&& !user.getHeadimgurl().equals("")) {
						respContent += "\n" + "<a href=\""
								+ user.getHeadimgurl() + "\" >点击查看用户头像</a>";
					}
				}
			} else {
				respContent = "该客户已被其他客服接走！";
			}
		}
		return respContent;
	}

	private String checkAccessState(String openid) {

		String respContent = "";

		AccessState sucessState = chatMsgService.getAccessState(
				Constants.ACCESS_SUCCESS_STATE, openid);
		if (sucessState == null) {

			// 等待接入中
			if (chatMsgService.isAccessState(Constants.REQUEST_ACCESS_STATE,
					openid)) {

				respContent = Constants.IN_ACCESS_STATE;
			} else {

				respContent = Constants.OUT_ACCESS_STATE;
			}
		}

		return respContent;
	}

	/**
	 * 判断当前客户是否在备注表中
	 * 
	 * @param chatmsg
	 */
	public void isExistCustomerRemark(ChatMsg chatmsg) {
		try {
			CustomerRemark customerRemark = chatMsgService
					.getCustomerRemark(chatmsg.getOpenid());
			if (customerRemark == null) {
				customerRemark = new CustomerRemark();
				customerRemark.setOpenid(chatmsg.getOpenid());
				WeixinUserInfo info = userService.getWeixinUserInfo(chatmsg
						.getOpenid());
				if (info != null) {
					customerRemark.setNickname(info.getNickname());
				}
				chatMsgService.saveCustomerRemark(customerRemark);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 返回聊天匹配编号
	public static String getCurrentMatchnumber(String currentMatchNumber) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(new Date());
		// String[] weeks = {"星期日","星期一","星期二","星期三","星期四","星期五","星期六"};
		int week_index = cal.get(Calendar.DAY_OF_WEEK) - 1;
		String d = "";
		if (week_index == 0) {
			d = "7";
		} else {
			d = week_index + "";
		}
		if (currentMatchNumber == null
				|| !currentMatchNumber.subSequence(0, 1).equals(d)) {
			d += "01";
		} else {
			d = (Integer.parseInt(currentMatchNumber) + 1) + "";
		}
		return d;
	}

	// 是否在工作时间内
	public boolean isInWorkTime() {
		Calendar calendar = Calendar.getInstance();
		// 初始化 Calendar 对象，但并不必要，除非需要重置时间
		calendar.setTime(new Date());
		int hour = calendar.get(Calendar.HOUR_OF_DAY);
		int minute = calendar.get(Calendar.MINUTE);
		if (hour < 8 || (hour == 8 && minute < 30) || hour > 17) {
			return false;
		}
		return true;
	}

	/**
	 * 请求客服
	 * 
	 * @param request
	 * @param chatmsg
	 * @param textMessage
	 * @param reqContent
	 * @return
	 */
	public synchronized String requestCustomerService(
			HttpServletRequest request, ChatMsg chatmsg) {

		String respContent = "";
		try {
			isExistCustomerRemark(chatmsg);

			// 清除是否有超过48小时未清理的记录
			chatMsgService.isOutTimeState();
			if (!isInWorkTime()) {
				respContent = "尊敬的客户，感谢您的关注，客服服务时间为8:30～18:00。";
			}
			// 查询是否已请求过，等待接入状态 1000
			else if (chatMsgService.isAccessState(
					Constants.REQUEST_ACCESS_STATE, chatmsg.getOpenid())) {
				respContent = Constants.IN_ACCESS_STATE;
			}
			// 查询是否已接入生成，接入状态 1001
			else if (chatMsgService.isAccessState(
					Constants.ACCESS_SUCCESS_STATE, chatmsg.getOpenid())) {
				respContent = "您已接入客服！";
			} else {
				AccessState aState = new AccessState();
				aState.setOpenid(chatmsg.getOpenid());
				aState.setOpercode(Constants.REQUEST_ACCESS_STATE);
				aState.setTime(chatmsg.getTime());
				aState.setWorker(null);
				String currentMatchNumber = null;

				// 把聊天匹配编号更新存入kefuNum表中
				KefuNum kefuNum = chatMsgService.getKefuNumById(1);
				currentMatchNumber = kefuNum.getMatchnumber() + "";
				currentMatchNumber = getCurrentMatchnumber(currentMatchNumber);
				System.out.println(chatmsg.getOpenid() + currentMatchNumber);
				kefuNum.setMatchnumber(Integer.parseInt(currentMatchNumber));
				chatMsgService.saveKefuNum(kefuNum);

				// 保存用户接入请求
				aState.setMatchnumber(Integer.parseInt(currentMatchNumber));
				chatMsgService.saveAccessState(aState);
				chatmsg.setMessage("400");
				chatmsg.setMatchnumber(aState.getMatchnumber());
				chatMsgService.saveChatMsg(chatmsg);

				// 通知400用户
				List<CustomerService> admins = (List<CustomerService>) mallCustomerServiceDao
						.findAll();
				CustomerRemark cr = chatMsgService.getCustomerRemark(chatmsg
						.getOpenid());
				String name = cr.getName() == null ? cr.getNickname() : cr
						.getName();
				for (CustomerService mallCustomerService : admins) {

					new PushUtil().sendResponse(
							mallCustomerService.getOpenid(),
							"客户\"" + name + "\"发起客服聊天，回复编号："
									+ aState.getMatchnumber() + "进行匹配！");
					// TemplateMsgService tmsAdmin = new TemplateMsgService(
					// mallCustomerService.getOpenid(),
					// aState.getMatchnumber() + "", "客户\"" + name
					// + "\"发起客服聊天，回复id编号进行匹配！");
					// tmsAdmin.sendMsg();
				}

				respContent = "Hi，欢迎使用微信客服，马上由人工客服为您服务，请稍候。";
			}
		} catch (NumberFormatException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return respContent;
	}

	public boolean isInChat(String openid) {

		// 清除是否有超过48小时未清理的记录
		chatMsgService.isOutTimeState();

		AccessState as = accessStateDao.findByOpenidOrWorker(openid);
		if (as != null && as.getOpercode() == Constants.ACCESS_SUCCESS_STATE) {
			return true;
		}
		return false;
	}

	public boolean isMallCustomerService(String openid, String reqContent) {
		CustomerService mcs = mallCustomerServiceDao.findOneByOpenid(openid);
		if (mcs != null && Util.isNumeric(reqContent)) {
			return true;
		}

		return false;
	}

	public void processMedia(Map<String, String> requestMap, ChatMsg chatmsg)
			throws Exception {
		String state = checkAccessState(chatmsg.getOpenid());
		AccessState as400 = chatMsgService.isAccess400(chatmsg.getOpenid());
		if (state.equals("") || as400 != null) {

			String url = "";
			String type = "";
			if ("image".equalsIgnoreCase(chatmsg.getMsgtype())) {
				url = "images/";
				type = "img";
			} else if ("voice".equalsIgnoreCase(chatmsg.getMsgtype())) {
				url = "voices/";
				type = "voice";
			}
			/*switch (chatmsg.getMsgtype()) {
			case "image":
				url = "images/";
				type = "img";
				break;

			case "voice":
				url = "voices/";
				type = "voice";
				break;
			}*/

			String picSavePath = getDownloadUrl(url);
			// String picUrl = requestMap.get("PicUrl");
			String mediaId = requestMap.get("MediaId");
			// 保存到服务器后返回的文件名
			String savedFileName = MediaUtil.downloadMedia(mediaId,
					picSavePath, type);
			chatmsg.setFileurl("/download/" + url + savedFileName);

			// 根据当前消息发送者的openid查询连接状态的openid信息，若查得到为用户，否则为客服
			AccessState as = chatMsgService.findByOpercodeAndOpenid(
					Constants.ACCESS_SUCCESS_STATE, chatmsg.getOpenid());
			if (as != null) {
				if (chatmsg.getMsgtype().equals("image")) {
					new PushUtil().sendResponseImg(as.getWorker(),
							requestMap.get("MediaId"));
				} else {
					new PushUtil().sendResponseVoice(as.getWorker(),
							requestMap.get("MediaId"));
				}

				chatmsg.setOrigin((short) 0);
				chatmsg.setOpenid(as.getOpenid());
				chatmsg.setWorker(as.getWorker());
				chatmsg.setMatchnumber(as.getMatchnumber());
			} else {
				if (chatmsg.getMsgtype().equals("image")) {
					new PushUtil().sendResponseImg(as400.getOpenid(),
							requestMap.get("MediaId"));
				} else {
					new PushUtil().sendResponseVoice(as400.getOpenid(),
							requestMap.get("MediaId"));
				}

				chatmsg.setOrigin((short) 1);
				chatmsg.setOpenid(as400.getOpenid());
				chatmsg.setWorker(as400.getWorker());
				chatmsg.setMatchnumber(as400.getMatchnumber());
			}
			chatMsgService.saveChatMsg(chatmsg);
		}
	}

	public String getDownloadUrl(String foldername) {
		// 当前类 文件的URI目录
		String rootPath = this.getClass().getResource("/").getPath();
		// 去除第一个字符"/"
		rootPath = rootPath.substring(1);

		String[] ss = rootPath.split("WEB-INF");

		return ss[0] + "download/" + foldername;
	}
}
